//
//  AppDelegate.swift
//  MT
//
//  Created by ooops on 2019/12/11.
//  Copyright © 2019 张强. All rights reserved.
//

import UIKit

import MTCategory
import JMessage
import DeviceKit
import AVFoundation
import SwiftyStoreKit
import RxCocoa
import Moya
import Result
import KTVHTTPCache
import RxSwift

enum RetryError: Error {
    case errorNumber
}

public protocol SelfAware: class {
    static func awake()
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    let userProvider: MTProvider = MTProvider<UserCenterApi>()
    
    private lazy var authProvider: MTProvider<DDCAuthAPI> = {
        let provider = MTProvider<DDCAuthAPI>()
        return provider
    }()
    
    private lazy var payProvider: MTProvider<MTPaymentAPI> = {
        let provider = MTProvider<MTPaymentAPI>()
        return provider
    }()

    var window: UIWindow?
    private var retryCount = 1           // 当前重试次数
    private let maxRetryCount = 5        // 最多重试次数

    fileprivate var hostReachability: Reachability!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        /// 获取支付的订单base64
        if let receiptDataString = UserDefaults.Enviroment.localReceiptBase64Data.storedString {
            payProvider.rx.requestResult(.iosPay(payload: receiptDataString)).subscribe(onNext: { (result:Result<MTPaymentModel, AnyError> , isCache:Bool) in
                switch result {
                case .success(let model):
                    if model.code == 200 {
                        /// 清除本地缓存的内购票据信息
                        UserDefaults.Enviroment.localReceiptBase64Data.store(value: nil)
                    }
                case .failure(_):
                    break
                }
                
            }).disposed(by: globalDisposedBag)
        } else {
            debugPrint("没有可验证的本地票据信息")
        }
        
        #if DEBUG
        if UserDefaults.Enviroment.env.storedInt == 0 {
            UserDefaults.Enviroment.env.store(value: TargetConfig.debug.rawValue)
        }
        #else
        UserDefaults.Enviroment.env.store(value: TargetConfig.release.rawValue)
        #endif
        
        let get5 = Single<Bool>.create(subscribe: { single in
            if self.retryCount == self.maxRetryCount {
                self.retryCount = 1
                single(.success(true))
            } else {
                self.retryCount += 1
                single(.error(RetryError.errorNumber))
            }
            return Disposables.create()
        })
        
        if let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
            authProvider.originRequest(.audit(version: version), callbackQueue: .main, progress: nil) { [weak self] (result, _) in
                guard let weakSelf = self else { return }
                switch result {
                case let .success(response):
                    if let datas = try? response.mapJSON() as? [String: Any], let code = datas["code"] as? Int, code == 200 {
                        if (datas["result"] as? Bool) != nil {
                            UserDefaults.AppValidate.isValidate.store(value: datas["result"] as! Bool)
                            debugPrint("validate -------------: ", UserDefaults.AppValidate.isValidate.storedBool)
                            weakSelf.setupWindow()
                        } else {
                            weakSelf.setupWindow()
                        }
                    }
                    break
                case .failure(_):
                    //weakSelf.request()
                    get5.asObservable()
                    .observeOn(MainScheduler.asyncInstance)
                    .retryWhen { (error) -> Observable<Int> in
                        return error.flatMap({ [weak self] (er) -> Observable<Int> in
                            guard let weakSelf = self else { return Observable.error(er) }
                            guard weakSelf.retryCount < weakSelf.maxRetryCount + 1 else {
                                return Observable.error(er)
                            }
                            return Observable.timer(1, scheduler: MainScheduler.instance)
                        })
                    }
                    .subscribe(onNext: { bool in
                        debugPrint("bool =", bool)
                    }, onError: { error in
                        switch (error as! RetryError) {
                        case .errorNumber:
                            debugPrint("number error")
                        }
                    }, onCompleted: {
                        debugPrint("completed")
                        weakSelf.setupWindow()
                    })
                    .disposed(by: globalDisposedBag)
                    break
                }
                
            }
        }
        
        MTShareManager.confitUShareSettings()
        
        //支付
        MTPayManager.manager.registAppid()
        // see notes below for the meaning of Atomic / Non-Atomic
        SwiftyStoreKit.completeTransactions(atomically: true) { purchases in
            for purchase in purchases {
                switch purchase.transaction.transactionState {
                case .purchased, .restored:
                    if purchase.needsFinishTransaction {
                        // Deliver content from server, then:
                        SwiftyStoreKit.finishTransaction(purchase.transaction)
                    }
                    // Unlock content
                case .failed, .purchasing, .deferred:
                    break // do nothing
                @unknown default:
                    break // do nothing
                }
            }
        }
        
        
        /// 获取本地缓存值
        UserCenter.default.setValueFromStoredValue()
        
        if #available(iOS 11.0, *) {
            UITableView.appearance().estimatedRowHeight = 0
            UITableView.appearance().estimatedSectionFooterHeight = 0
            UITableView.appearance().estimatedSectionHeaderHeight = 0
            UITableView.appearance().showsVerticalScrollIndicator = false
        }
        
        registerJPush(application: application, options: launchOptions)
        setupJMessage(options: launchOptions)
        
        MTUmengLogin.registApp()
        
        hostReachability = Reachability(hostName: "www.apple.com")
        hostReachability.startNotifier()
        _ = JCVerificationInfoDB.shareInstance
        OpenInstallSDK.initWith(self)
        
        do {
            _ = try? KTVHTTPCache.proxyStart()
        }
        return true
    }
    /// 失败重试
    private func request() {
        if let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
            authProvider.originRequest(.audit(version: version), callbackQueue: .main, progress: nil) { [weak self] (result, _) in
                guard let weakSelf = self else { return }
                switch result {
                case let .success(response):
                    if let datas = try? response.mapJSON() as? [String: Any], let code = datas["code"] as? Int, code == 200 {
                        if (datas["result"] as? Bool) != nil {
                            UserDefaults.AppValidate.isValidate.store(value: datas["result"] as! Bool)
                            debugPrint("validate -------------: ", UserDefaults.AppValidate.isValidate.storedBool)
                        }
                    }
                    break
                case .failure(_):
                    weakSelf.request()
                    break
                }
                
            }
        }
    }
    
    private func setupWindow() {
        DispatchQueue.main.async {
            //实例化window
            self.window = UIWindow(frame: UIScreen.main.bounds)
            
            self.window?.backgroundColor = .white
            self.window?.makeKeyAndVisible()
            if UserDefaults.MTUserCenter.userStatus.storedInt == 1 {
                let vc: UIViewController = BaseTabBarViewController()
                self.window?.rootViewController = vc
            } else {
                let c = MTLoginViewController()
                let nav = BaseNavController(rootViewController: c)
                self.window?.rootViewController = nav
            }
        }
    }
    
    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        
        UMSocialManager.default().handleOpen(url,sourceApplication: sourceApplication, annotation: annotation)
        return true
    }
    
    internal func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        
        UMSocialManager.default().handleOpen(url, options: options)
        _ = MTPayManager.manager.handleOpenURL(url: url)
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        try? AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        resetBadge(application)
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        resetBadge(application)
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        _getConversations()
    }

    func applicationWillTerminate(_ application: UIApplication) {
        /// 如果实在聊天室界面退出了程序, 需要退出聊天室, 否则下次进入聊天室, 看不到历史消息
        let roomId = UserDefaults.MTUserCenter.roomId.storedInt
        JMSGChatRoom.leaveChatRoom(withRoomId: "\(roomId)") { (result, error) in
            
        }
    }
    
    private func resetBadge(_ application: UIApplication) {
        application.applicationIconBadgeNumber = 0
//        application.cancelAllLocalNotifications()
        UNUserNotificationCenter.current().removeAllDeliveredNotifications()
        JMessage.resetBadge()
    }
    
    //注意，swift4.2版本，系统方法修改为：
    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool{
        if OpenInstallSDK.continue(userActivity){return true}//如果使用了Universal link ，此方法必写
        //其他第三方回调:
        return true
    }
    
}


extension AppDelegate: OpenInstallDelegate {
    
    func getWakeUpParams(fromOpenInstall params: [AnyHashable : Any]?, withError error: Error?) {
        debugPrint("------------", params)
    }
    
    
    
}
